#pragma once

#include"host_info.h"
#include<ext/hash_map>
#include<list>
#include"lars.pb.h"


// ip和port作为主键，host_info作为value的map
typedef __gnu_cxx::hash_map<uint64_t, host_info*> host_map;
typedef host_map::iterator host_map_it;

//host_info list集合
typedef std::list<host_info*> host_list; 
typedef host_list::iterator host_list_it;


// 针对一个modid和cmdid下的全部节点下做负载均衡
class load_balance{
public:
    load_balance(int modid, int cmdid);

    // 向远程的DNS服务中发送ID_GetRouteRequest请求
    int pull();
    // 将dns返回的数据中的host信息添加到当前的load_balance中
    int update(lars::GetRouteResponse &response);

    // 判断当前的load_balance是否是空的，是否只有mod，没有host信息
    bool empty(){
        return _host_map.empty();
    }

    // 获取一个可用的host信息
    int choice_one_host(lars::GetHostResponse &response);
    // 从idel_list或者overload_list中得到一个host节点
    void get_host_from_list(lars::GetHostResponse &response, host_list &list);

    // 根据api上报的信息调整内部节点
    void report(int ip, int port, int retcode);
    // 将当前的load_balance中的host情况发送给report_queue，用于上报远程reporter service服务器
    void commit();

    // 获取当前的所有host信息
    void get_all_hosts(lars::GetRouteResponse &response);

    // 设置一个状态位，防止重复拉取一个数据
    enum STATUS{
        PULLING,    // 正在从远程dns service拉取数据中
        NEW,        // 正在创建新的load_balance模块
    };

    STATUS _status;  // 表示当前的状态

    // 设置一个当前lb的最后一次更新时间
    long _last_update_time;
    
private:
    int _modid;
    int _cmdid;

    // 当前负载均衡模块所管理的全部主机
    host_map _host_map;

    // 空闲队列
    host_list _idle_list;

    // 过载队列
    host_list _overload_list;

    // 设置一个请求次数参数
    int _access_cnt;

    

};